Pipelines CI/CD y Flujo GitOps
1. Pipeline de Integración Continua (Jenkins CI)
El pipeline de CI se define mediante un archivo declarativo (Jenkinsfile) que se ejecuta de manera efímera dentro del clúster de Kubernetes.
Ejemplo de Configuración Real: Jenkinsfile Declarativo Empresarial
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: jenkins-agent
spec:
containers:
- name: maven
image: maven:3.9.6-eclipse-temurin-17
command: ['cat']
tty: true
- name: docker
image: docker:24.0.7-dind
securityContext:
privileged: true
command: ['cat']
tty: true
- name: trivy
image: aquasec/trivy:0.48.1
command: ['cat']
tty: true
'''
}
}
environment {
DOCKER_REGISTRY = 'registry.alpura.com'
IMAGE_NAME = 'msa-sales-backend'
SONAR_PROJECT = 'alpura-msa-sales-backend'
GITOPS_REPO = 'github.com/alpura-enterprise/msa-infra-gitops.git'
CREDENTIALS_ID = 'jenkins-github-ssh'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Compilation') {
steps {
container('maven') {
sh 'mvn clean compile -DskipTests'
}
}
}
stage('Unit Tests & Coverage') {
steps {
container('maven') {
sh 'mvn test jacoco:report'
}
}
}
stage('SonarQube Quality Gate') {
steps {
container('maven') {
withSonarQubeEnv('SonarQube-Enterprise') {
sh "mvn sonar:sonar -Dsonar.projectKey=${SONAR_PROJECT}"
}
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
stage('Container Image Scan') {
steps {
container('trivy') {
sh "trivy image --severity HIGH,CRITICAL --exit-code 0 ."
}
}
}
stage('Docker Build & Push') {
steps {
container('docker') {
withCredentials([usernamePassword(credentialsId: 'docker-registry-auth', usernameVariable: 'REG_USER', passwordVariable: 'REG_PWD')]) {
sh "docker login ${DOCKER_REGISTRY} -u ${REG_USER} -p ${REG_PWD}"
sh "docker build -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} ."
sh "docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}"
}
}
}
}
stage('Update GitOps Manifest') {
steps {
withCredentials([gitUsernamePassword(credentialsId: 'github-app-token', gitToolName: 'git-tool')]) {
sh """
git config --global user.email "devops-bot@alpura.com"
git config --global user.name "Alpura DevOps Bot"
git clone https://${GITOPS_REPO}
cd msa-infra-gitops/apps/${IMAGE_NAME}/overlays/dev
sed -i 's|newTag:.*|newTag: "${BUILD_NUMBER}"|g' kustomization.yaml
git add kustomization.yaml
git commit -m "chore(cd): promote ${IMAGE_NAME} to version ${BUILD_NUMBER} in dev"
git push origin dev
"""
}
}
}
}
post {
always {
cleanWs()
}
}
}
7. Pipeline de Entrega Continua (Argo CD CD)
Argo CD ejecuta la conciliación continua detectando el estado deseado en Git y forzándolo en el clúster mediante un flujo estructurado:
Definición del Manifiesto: Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: msa-sales-backend-prod
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: sales-domain
source:
repoURL: 'https://github.com/alpura-enterprise/msa-infra-gitops.git'
targetRevision: main
path: apps/msa-sales-backend/overlays/prod
destination:
server: 'https://kubernetes.default.svc'
namespace: sales-prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 10s
factor: 2
maxDuration: 3m
8. Flujo y Gobierno GitOps Completo
Flujo de Liberación y Aprobaciones Completo
El siguiente flujo gráfico detalla de forma exhaustiva el camino que recorre un cambio en la organización, desde que el desarrollador crea el código hasta su ejecución final estable en Kubernetes.
[ REPOSITORIO DE APLICACIÓN ]
│
├──> 1. Crea Rama Feature <─── [ Dev Junior / Mid / Senior ]
│
├──> 2. Pull Request (PR) a Main o Develop
│ │
│ └──> 📑 APROBACIÓN REQUERIDA (Code Review)
│ └──> Mínimo:
│ • Dev Senior o Tech Lead
│ • Arquitecto de Software
│
└──> 3. Pipeline CI (Jenkins)
│
├── Checkout
├── Build & Compile
├── Unit Test
├── Static Analysis (SonarQube)
├── Quality Gate (Falla si no cumple)
├── Build Docker Image
├── Vulnerability Scan (Trivy/Snyk)
├── Push Docker Registry
└── Actualiza automáticamente el repositorio GitOps
│
▼
[ REPOSITORIO DE CONFIGURACIÓN (GitOps) ]
│
├── Manifiestos Kubernetes (Kustomize Overlays)
├── Helm Charts base y globales
├── Valores por ambiente (values-dev.yaml, values-prod.yaml)
├── Estructura de Namespaces, Network Policies
└── Versiones de imágenes por contenedor (Inmutables)
│
├──> 4. Pull Request (Automático o Manual de Promoción)
│
│ └── 🔐 AUTORIZACIÓN OBLIGATORIA
│
│ • Arquitecto Enterprise
│ • Product Owner (PO)
│
│ Ambos deben firmar con Check en GitHub para avanzar a PROD.
│
└──> 5. Merge a Rama Main del Repo GitOps
│
▼
[ OPERADOR GITOPS ]
Argo CD (Instalado internamente en K8s)
│
Detecta cambios en Git (Pull cada 3 min o vía Webhook)
│
Compara Estado Actual del Clúster vs Estado Deseado en Git
│
Ejecuta la sincronización (Sync)
│
Rolling Update sin pérdida de servicio
│
Verificación de Health Checks
│
Validación del Deployment y Tráfico
│
▼
Clúster Kubernetes (Estado Deseado Sincronizado)
Diagrama de Secuencia de Procesos de GitOps
Tabla de Gobierno: Pull vs Push
| Criterio de Comparación | Modelo Pull-Based GitOps (ArgoCD) | Modelo Push-Based CI/CD (Jenkins Directo) |
|---|---|---|
| Seguridad del Clúster | Alta: El clúster no expone puertos ni API externa; ArgoCD jala cambios desde dentro. | Baja: El motor CI debe poseer credenciales de Admin del clúster (kubeconfig) expuestas externamente. |
| Auditoría y Trazabilidad | Inmutable: Cada cambio físico en el clúster corresponde exactamente a un commit firmado en Git. | Efímera: Desafíos para correlacionar quién detonó una acción manual de despliegue directo en el servidor CI. |
| Recuperación ante Desastres | Instantánea: Reconstrucción total del clúster en minutos clonando y sincronizando el repo GitOps. | Compleja: Depende de respaldos manuales o de ejecutar múltiples pipelines secuenciales en el orden correcto. |
| Prevención de Drift (Desviación) | Automática: ArgoCD sobrescribe inmediatamente cualquier cambio manual local no declarado en Git. | Inexistente: Si un operador altera un Deployment usando kubectl edit, el motor CI no se entera. |
| Cumplimiento y Gobierno | Garantizado: Toda promoción requiere PR aprobados por roles segregados de arquitectura y negocio. | Débil: El pipeline tiene control total y puede mezclar responsabilidades de desarrollo y despliegue. |